%%html
<style>
div.input {
display:none;
}
</style>
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
%matplotlib inline
import seaborn as sns
import plotly.express as px
from plotly.subplots import make_subplots
sns.set(context="notebook", style="whitegrid", palette="deep", font="Arial", font_scale=1, color_codes=True)
from sklearn.linear_model import LinearRegression
from datetime import timedelta
import plotly.graph_objects as go
import scipy.optimize as opt
from statsmodels.api import OLS
from IPython.display import display, HTML
data_src="https://github.com/CSSEGISandData/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_time_series/"
cfm=pd.read_csv(data_src+"time_series_covid19_confirmed_global.csv")
dt=pd.read_csv(data_src+"time_series_covid19_deaths_global.csv")
##rc=pd.read_csv(data_src+"time_series_19-covid-Recovered.csv")
def trans_df(df, valname):
out=pd.DataFrame(columns=["Country/Region","Province/State","Lat","Long",
"LastUpdated",valname])
for j in df.columns[4:]:
nval=pd.notnull(df[j])
blk=df[nval][["Country/Region","Province/State","Lat","Long"]]
blk['LastUpdated']=pd.to_datetime(j)
blk[valname]=df[nval][j]
out=out.append(blk,ignore_index=True,sort=False)
out[valname]=out[valname].astype(int)
return(out)
df_cfm=trans_df(cfm,"Confirmed")
df_dt=trans_df(dt,"Death")
##df_rc=trans_df(rc,"Recovered")
df=pd.merge(df_cfm,df_dt,on=['Country/Region','Province/State','Lat','Long','LastUpdated'],how='left')
##df=pd.merge(df,df_rc,on=['Country/Region','Province/State','Lat','Long','LastUpdated'],how='left')
df.rename(columns={'Country/Region':'Country', 'Province/State':'Region','LastUpdated':'Date_updated'},inplace=True)
df.Region.fillna('',inplace=True)
df['Date_updated']=pd.to_datetime(df['Date_updated'])
maxdate=df['Date_updated'].max()
#df=df[df.Date_updated <= '2020-03-28']
print(f'Data version: {maxdate.strftime("%Y-%m-%d")}')
can=pd.read_csv("https://health-infobase.canada.ca/src/data/covidLive/covid19.csv")
can['date']=pd.to_datetime(can['date'],format='%d-%m-%Y')
can=can[can['date']<=maxdate]
can[['prname']]=can[['prname']].replace('Repatriated Travellers','Repatriated travellers',regex=False)
tmp=pd.DataFrame({'Country':'Canada','Region':can.loc[can['prname']!='Canada', 'prname'],
'Date_updated':can.loc[can['prname']!='Canada', 'date'],
'Confirmed':can.loc[can['prname']!='Canada', 'numtotal'],
'Death':can.loc[can['prname']!='Canada', 'numdeaths']})
radec=df.loc[df['Country']=='Canada',['Region','Lat','Long']].drop_duplicates()
tmp=tmp.merge(radec,how='left',on='Region').reset_index(drop=True)
df=df[df['Country']!='Canada'].append(tmp,ignore_index=True)
df.sort_values(by=['Date_updated','Country','Region'],inplace=True)
#fix BC data issue
#df.loc[(df.Region=="British Columbia") & (df.Date_updated=='2020-03-17'), ['Confirmed','Death']]=[186,7]
#df.loc[(df.Region=="British Columbia") & (df.Date_updated=='2020-03-18'), ['Confirmed','Death']]=[231,7]
#df.loc[(df.Region=="British Columbia") & (df.Date_updated=='2020-03-19'), ['Confirmed','Death']]=[271,8]
#df.loc[(df.Region=="British Columbia") & (df.Date_updated=='2020-03-20'), ['Confirmed','Death']]=[348,9]
#df.loc[(df.Region=="British Columbia") & (df.Date_updated=='2020-03-22'), ['Confirmed','Death']]=[472,12]
#df.loc[(df.Region=="British Columbia") & (df.Date_updated=='2020-03-23'), ['Confirmed','Death']]=[539,12]
#df.loc[(df.Region=="British Columbia") & (df.Date_updated=='2020-03-27'), ['Confirmed','Death']]=[792,16]
#df.loc[(df.Region=="British Columbia") & (df.Date_updated=='2020-03-29'), ['Confirmed','Death']]=[900,17]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-10'), ['Confirmed','Death']]=[16,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-11'), ['Confirmed','Death']]=[24,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-12'), ['Confirmed','Death']]=[26,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-13'), ['Confirmed','Death']]=[34,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-14'), ['Confirmed','Death']]=[53,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-15'), ['Confirmed','Death']]=[63,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-16'), ['Confirmed','Death']]=[86,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-17'), ['Confirmed','Death']]=[100,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-18'), ['Confirmed','Death']]=[128,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-19'), ['Confirmed','Death']]=[155,0]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-20'), ['Confirmed','Death']]=[199,1]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-21'), ['Confirmed','Death']]=[237,1]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-22'), ['Confirmed','Death']]=[280,1]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-23'), ['Confirmed','Death']]=[331,1]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-24'), ['Confirmed','Death']]=[395,1]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-25'), ['Confirmed','Death']]=[472,2]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-26'), ['Confirmed','Death']]=[525,2]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-27'), ['Confirmed','Death']]=[610,2]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-28'), ['Confirmed','Death']]=[664,2]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-29'), ['Confirmed','Death']]=[688,2]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-03-30'), ['Confirmed','Death']]=[735,8]
#df.loc[(df.Region=="Alberta") & (df.Date_updated=='2020-04-01'), ['Confirmed','Death']]=[871,11]
tmp=df[['Date_updated','Country','Region','Confirmed','Death']].copy()
tmp['Date_updated_1']= tmp['Date_updated']+timedelta(days=1)
new=pd.merge(tmp,tmp,how='left',
left_on=['Country','Region','Date_updated'],
right_on=['Country','Region','Date_updated_1'],
suffixes=['_current','_before'])
new['Confirmed_added']=new['Confirmed_current']-new['Confirmed_before']
new['Death_added']=new['Death_current']-new['Death_before']
new.rename(columns={'Date_updated_current':'Date_updated'},inplace=True)
df=pd.merge(df,new[['Date_updated','Country','Region','Confirmed_added','Death_added']],
how='left',on=['Date_updated','Country','Region'])
#df[(df.Country=='Canada') & (df.Date_updated=='2020-04-01')].sort_values('Confirmed',ascending = False)
df_country=df.groupby(['Country','Date_updated'])[['Confirmed','Death','Confirmed_added','Death_added']].sum().reset_index()
df_now=df_country.groupby('Country')[['Confirmed','Death']].max().reset_index()
dfa=df_country[df_country.Country.isin(df_now[df_now.Confirmed > 300]['Country'])].copy()
dfa.loc[:,'StartDate']=-999
for j in dfa.Country.unique():
sdate=dfa.loc[(dfa.Country==j) & (dfa.Confirmed > 100),'Date_updated'].min()
##print(f"Country: {j} case number: {dfa[(dfa.Country==j) & (dfa.Confirmed > 100)]['Confirmed'].min()} start date {sdate}")
tmp=dfa.loc[dfa.Country==j,'Date_updated']-sdate
dfa.loc[dfa.Country==j,'StartDate']=tmp.dt.days + 1
if j == 'China':
dfa.loc[dfa.Country==j,'StartDate']+=5
When aligned by the first day since the 100th case in each country, the total confirmed case number of all the countries grow similarly except for a few: it follows a steep exponential growth at the early stage which is resulted from an unhampered epidemic spread, gradually slows down after various countermeasures are taken by the governments and eventually goes to flat when the situation is under control.
Countries that are successful in the early prevention and control, like Japan and Singapore, show a much shallower growth with time; South Korea experienced a rapid growth at the early stage but managed to flatten out the curve very quick by an aggressive 'trace, test and treat' strategy.
Canada currently is still in the early rising stage with a growth rate similar to many European countries. The countermeasures taken by the governments are yet to significantly slow down the growth.
Three northern European countries, Sweden, Norway and Denmark, show much shallower growth compared to other countries and this has led to a lot of discussions on the cultural difference of the northern countries that might help to enforce the social distance more effectively.
Two European countries, Czechia and Austria, have been requiring their risidents to wear face masks in public, which is different from other country's policy. It is interesting to monitoring their case growth to see the impact of this difference.
#countrylist=allcountrylist[:10]
#countrylist.append('Japan')
cl=px.colors.qualitative.Dark24
cblue=cl[0]
corange=cl[8]
cgreen=cl[2]
cred=cl[3]
cl2=[x for x in cl if x not in [cblue,corange,cgreen,cred]]
#countrylist.remove('China').remove('Korea, South').remove('Italy')
fig=px.line(log_y=True,range_x=[0,150],range_y=[100,1500000],width=1000, height=600)
#fig=px.line(dfa[dfa.Country.isin(countrylist)],x='StartDate',y='Confirmed',color='Country',log_y=True
# ,range_x=[0,40],range_y=[100,100000])
cty='China'
clr=cblue #blue
fig.add_scatter(x=dfa.loc[dfa.Country==cty,'StartDate'],y=dfa.loc[dfa.Country==cty,'Confirmed']
,mode="lines",name=cty,line=dict(width=2, color=clr))
cty='Italy'
clr=corange #Orange
fig.add_scatter(x=dfa.loc[dfa.Country==cty,'StartDate'],y=dfa.loc[dfa.Country==cty,'Confirmed']
,mode="lines",name=cty,line=dict(width=2, color=clr))
cty='US'
clr=cgreen #green
fig.add_scatter(x=dfa.loc[dfa.Country==cty,'StartDate'],y=dfa.loc[dfa.Country==cty,'Confirmed']
,mode="lines",name=cty,line=dict(width=2,color=clr))
ctryl=['Spain','Germany','Iran','France','Switzerland','United Kingdom','Japan',
'Singapore','Czechia','Denmark','Sweden','Austria','Norway','Brazil','Russia']
for j in range(len(ctryl)):
fig.add_scatter(x=dfa.loc[dfa.Country==ctryl[j],'StartDate'],y=dfa.loc[dfa.Country==ctryl[j],'Confirmed']
,mode="lines",name=ctryl[j],line=dict(width=2,color=cl2[j]))
cty='Korea, South'
clr='yellow'
fig.add_scatter(x=dfa.loc[dfa.Country==cty,'StartDate'],y=dfa.loc[dfa.Country==cty,'Confirmed']
,mode="lines",name=cty,line=dict(width=2,color=clr))
cty='Canada'
clr=cred #red
fig.add_scatter(x=dfa.loc[dfa.Country==cty,'StartDate'],y=dfa.loc[dfa.Country==cty,'Confirmed']
,mode="lines+markers",name=cty,marker=dict(size=2,color=clr,line=dict(width=4,color=clr)))
fig.update_layout(
title="COVID-19 Cases by Country",title_x=0.5,
xaxis=dict(showline=True,showgrid=True,showticklabels=True,linecolor='black',linewidth=2,
ticks='outside', mirror=True,
gridcolor="rgba(0,0,0,0.2)",
tickfont=dict(
family='Arial',
size=12,
color='black',
)),
yaxis=dict(showline=True,showgrid=True,showticklabels=True,linecolor='black',linewidth=2,
ticks='inside',mirror=True,
gridcolor="rgba(0,0,0,0.2)",
tickfont=dict(
family='Arial',
size=12,
color='black',
)),
plot_bgcolor='white',
xaxis_title="Number of Days since 100th Case",
yaxis_title="Confirmed Case",
font=dict(
family="Arial",
size=14,
color="black"
)
)
fig.show()
fig.write_image("output/trend_by_country"+ dfa.Date_updated.max().strftime('_%m_%d_%Y')+".jpeg", scale=3)
s1_cnd=dfa.loc[(dfa.Country=='Canada') & (dfa.Confirmed > 1000),'Date_updated'].min()
pred=pd.DataFrame({'Date_updated':[ s1_cnd + timedelta(days=x-9) for x in range(150)]})
pred=pred.merge(dfa.loc[dfa.Country=='Canada',['Date_updated','Confirmed']], how='left',on='Date_updated')
dcan=dfa.loc[dfa.Country=='Canada',['Date_updated','Confirmed']].tail(5)
x=np.arange(10)
xx=np.array([np.repeat(1,10),x]).transpose()
mod=OLS(np.log(dcan['Confirmed']), xx[:5]).fit()
pdx=mod.get_prediction(xx)
predmean=np.exp(pdx.predicted_mean)
conf=np.exp(pdx.conf_int(alpha=0.05))
out=pd.DataFrame({'Date_updated': dcan['Date_updated'].append(dcan['Date_updated']+timedelta(days=5)),
'predict':predmean,
'cf_low':conf[:,0],'cf_high':conf[:,1]})
pred=pred.merge(out,how='left',on='Date_updated')
pred['Daily Adds']=float('nan')
tmp=pred.Confirmed.iloc[1:(len(pred)-1)].values-pred.Confirmed.iloc[0:(len(pred)-2)].values
pred.iloc[1:(len(pred)-1),5]=tmp.copy()
cty='US'
tmp=dfa.loc[dfa.Country==cty,['Date_updated','Confirmed']]
tmp['Date_updted_'+cty]=tmp['Date_updated']
tmp['Date_updated']=tmp['Date_updated'] - tmp.loc[tmp.Confirmed > 1000, 'Date_updated'].min() + s1_cnd
tmp.rename(columns={"Confirmed": cty + " - Date Adjusted"}, inplace=True)
pred=pred.merge(tmp,how='left', on='Date_updated')
cty='Brazil'
tmp=dfa.loc[dfa.Country==cty,['Date_updated','Confirmed']]
tmp['Date_updted_'+cty]=tmp['Date_updated']
tmp['Date_updated']=tmp['Date_updated'] - tmp.loc[tmp.Confirmed > 1000, 'Date_updated'].min() + s1_cnd
tmp.rename(columns={"Confirmed": cty + " - Date Adjusted"}, inplace=True)
pred=pred.merge(tmp,how='left', on='Date_updated')
cty='Russia'
tmp=dfa.loc[dfa.Country==cty,['Date_updated','Confirmed']]
tmp['Date_updted_'+cty]=tmp['Date_updated']
tmp['Date_updated']=tmp['Date_updated'] - tmp.loc[tmp.Confirmed > 1000, 'Date_updated'].min() + s1_cnd
tmp.rename(columns={"Confirmed": cty + " - Date Adjusted"}, inplace=True)
pred=pred.merge(tmp,how='left', on='Date_updated')
cty='United Kingdom'
tmp=dfa.loc[dfa.Country==cty,['Date_updated','Confirmed']]
tmp['Date_updted_'+cty]=tmp['Date_updated']
tmp['Date_updated']=tmp['Date_updated'] - tmp.loc[tmp.Confirmed > 1000, 'Date_updated'].min() + s1_cnd
tmp.rename(columns={"Confirmed": cty + " - Date Adjusted"}, inplace=True)
pred=pred.merge(tmp,how='left', on='Date_updated')
eve=[['2020-03-13','Recommendation against Intl. travel'],
['2020-03-16','State of Emergency'],
['2020-03-17','Restricted entry into Canada'],
['2020-03-20','US-Canada border closed for non-essential travel'],
['2020-03-24','Quarantine Act invoked'],
['2020-03-30','Domestic travel restriction']]
eve=pd.DataFrame(eve, columns=['Date_updated','events'])
eve.Date_updated=pd.to_datetime(eve.Date_updated)
pred=pred.merge(eve,how='left',on='Date_updated')
pred.to_csv('output/CanadaGrowth'+ dfa.Date_updated.max().strftime('_%m_%d_%Y')+'.csv')
Since Canada is still at the exponential growth period, an exponential projection provides a good short-term forecast. In the following chart, the next 5 day's case number is projected based on the exponential growth of the previous 5 day's actual case numbers. The different countermeasures taken by the government are timelined on the chart to monitor their impacts on the growth.
After reaching 1000 cases, the growth rate of Canada is actually not very different from the growth rate of many other countries when they had a similar number of cases. The plot below shows the growth curve of Canada vs US, Italy, Korean and China after other countries' dates are backshifted. The trajectories of those countries provide different scenaria on the long term case growth in Canada.
As of today, we can see that the Canada growth curve finally started to fall below both US and Italy, suggesting we are slowing down faster than those countries.
fig=px.line(log_y=True,range_x=['2020-03-08','2020-07-15'],range_y=[100,2500000],width=900, height=600)
captext="Canada COVID-19 case growth with time. US, Brazil, Russia and UK's curves are shifted by days to align with<br>"\
+ "the 1000th case day in Canada. Exponential projection of the future 5 days are calculated using the previous 5 day<br>"\
+"numbers. The shaded area indicates the 95% confidence interval of the projection."
cl=['green','orange','gold','blue']
cty=['US', 'Brazil', 'Russia', 'United Kingdom']
lname=['US - date shifted', 'Brazil - date shifted',
'Russia - date shifted','United Kingdom - date shifted']
for i in range(len(cl)):
fig.add_scatter(x=pred['Date_updated'],y=pred[cty[i] +' - Date Adjusted'], mode="lines",
name=lname[i],line=dict(width=3,color=cl[i]))
fig.add_trace(go.Scatter(x=pred['Date_updated'], y=pred['cf_low'],
fill=None, mode='lines',line_color='rgba(0,0,0,0)',showlegend=False))
fig.add_trace(go.Scatter(x=pred['Date_updated'], y=pred['cf_high'],
fill='tonexty',mode='lines', line_color='rgba(256,0,0,0.3)',showlegend=False))
fig.add_scatter(x=pred['Date_updated'],y=pred['predict'], mode="lines",
name='Canada exponential projection',line=dict(width=2, color='red', dash='dot'))
fig.add_scatter(x=pred['Date_updated'],y=pred['Confirmed'], mode="lines+markers+text",
name='Canada',marker=dict(size=5,color='red'),
text=pred['events'],textposition="bottom right",
textfont=dict(family="Ariel",size=14,color='red'))
fig.update_layout(title='Canada COVID-19 Case Growth Curve',title_x=0.5,
titlefont=dict(family='Arial',size=28,color='black'),
plot_bgcolor='white',
xaxis=dict(titlefont=dict(family='Ariel, sans-serif',size=11, color='black'),
showline=True,showgrid=True,showticklabels=True,linecolor='black',
linewidth=2,ticks='outside', mirror=False,
gridcolor="rgba(0,0,0,0.1)",
tickfont=dict(family='Arial',size=15,color='black'),
tickformat= "%d-%b"
),
yaxis=dict(title='Confirmed Case', titlefont=dict(family='Ariel',size=18, color='black'),
showline=True,showgrid=True,showticklabels=True,linecolor='black',
linewidth=2,ticks='outside', mirror=False,
gridcolor="rgba(0,0,0,0.1)",
tickfont=dict(family='Arial',size=15,color='black')
),
legend=dict(x=0.63, y=0.05,
font=dict(family="Ariel",size=16,color="black"), bgcolor='rgba(0,0,0,0)'),
margin = dict(l = 50, r = 50, t = 60, b = 120),
annotations = [dict(x = -0.08, y = -0.25, align='left',
text = captext, showarrow = False, xref='paper', yref='paper',
xanchor='left', yanchor='auto', xshift=0, yshift=0,
font=dict(family='Arial',size=16, color="grey"))]
)
fig.show()
fig.write_image("output/Canada_growth_"+ dfa.Date_updated.max().strftime('_%m_%d_%Y')+".jpeg", scale=3)
Projected case number in the next 5 days:
outtable=pred.loc[~pred.predict.isna(),['Date_updated','Confirmed','predict','cf_low','cf_high','Daily Adds']].tail(8).copy()
outtable['Date']=outtable['Date_updated'].dt.strftime('%B %d')
outtable['Actual']=[ f"{x:,.0f}" if ~np.isnan(x) else '' for x in outtable['Confirmed'] ]
outtable['Projection']=[f"{x:,.0f}" for x in outtable['predict']]
outtable['Daily Adds']=[f"{x:,.0f}" if ~np.isnan(x) else '' for x in outtable['Daily Adds'] ]
outtable=outtable[['Date','Actual','Projection','Daily Adds']].set_index('Date').T
display(HTML(outtable.to_html()))
fig = make_subplots(
rows=5, cols=1,
subplot_titles=("Canada","US", "Brazil","Russia","UK"),
vertical_spacing=0.08,
specs=[[{"secondary_y": True}],
[{"secondary_y": True}],
[{"secondary_y": True}],
[{"secondary_y": True}],
[{"secondary_y": True}]])
bw=1000*3600*24
oneday=86400000.0
date_max='2020-06-25'
#Canada
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='Canada','Date_updated'],
y=dfa.loc[dfa.Country=='Canada','Confirmed_added'] ,
name='Case',
marker_color='rgb(55, 83, 109)',
width=bw*0.5
),
row=1, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='Canada','Date_updated'],
y=dfa.loc[dfa.Country=='Canada','Death_added'] ,
name='Death',
marker_color='blue',
width=bw*0.5
),
row=1, col=1, secondary_y=True)
fig.add_trace(go.Bar(x=pd.to_datetime(['2020-02-26','2020-03-13','2020-03-17','2020-03-25'])
, y=np.repeat(100000,4),name='events', marker_color='rgb(256,0,0)', width=bw*0.2,showlegend=False),
row=1,col=1, secondary_y=False)
fig.add_annotation(x=pd.to_datetime('2020-02-26'), y=2700, ax=140, ay=0, xref='x1',yref='y1',arrowhead=1,
align='left',text="Minister of Health issued warning for COVID-19", font=dict( size=11))
fig.add_annotation(x=pd.to_datetime('2020-03-13'), y=2500, ax=100, ay=0, xref='x1',yref='y1',arrowhead=1,
align='left',text="Recommendation against Intl. travel", font=dict( size=11))
fig.add_annotation(x=pd.to_datetime('2020-03-17'),y=2200, ax=110, ay=0, xref='x1',yref='y1',arrowhead=1,
align='left',text="Travel bans; State of Emergency by Provs", font=dict( size=11))
fig.add_annotation(x=pd.to_datetime('2020-03-25'), y=2000, ax=60, ay=0,xref='x1',yref='y1',arrowhead=1,
align='left',text="Quarantine Act", font=dict( size=11))
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-03-10',date_max]), row=1, col=1,showgrid=True)
yr=2800
fig.update_yaxes(title_text='Case',range=[0,yr], row=1, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/5.], row=1, col=1, secondary_y=True,color='blue')
#US
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='US','Date_updated'],
y=dfa.loc[dfa.Country=='US','Confirmed_added'] ,
name='US',
marker_color='rgb(55, 83, 109)',
width=bw*0.5,showlegend=False
),
row=2, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='US','Date_updated'],
y=dfa.loc[dfa.Country=='US','Death_added'] ,
name='US',
marker_color='blue',
width=bw*0.5,showlegend=False
),
row=2, col=1, secondary_y=True)
fig.add_trace(go.Bar(x=pd.to_datetime(['2020-02-29','2020-03-19'])
, y=np.repeat(100000,2),name='events', marker_color='rgb(256,0,0)',width=bw*0.2,showlegend=False),
row=2, col=1, secondary_y=False)
fig.add_annotation(x=pd.to_datetime('2020-02-29'),y=38000, ax=80, ay=0, xref='x2', yref='y3',arrowhead=1,
text="WA: State of Emergency",font=dict( size=11))
fig.add_annotation(x=pd.to_datetime('2020-03-19'), y=36000, ax=100, ay=0, xref='x2', yref='y3',arrowhead=1,
text="More states lockdown; Travel bans",font=dict( size=11))
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-02-23',date_max]), row=2, col=1,showgrid=True)
yr=40000
fig.update_yaxes(title_text='Case',range=[0,yr], row=2, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/5.], row=2, col=1, secondary_y=True,color='blue')
#Brazil
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='Brazil','Date_updated'],
y=dfa.loc[dfa.Country=='Brazil','Confirmed_added'] ,
name='Brazil',
marker_color='rgb(55, 83, 109)',
width=bw*0.5,showlegend=False
),
row=3, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='Brazil','Date_updated'],
y=dfa.loc[dfa.Country=='Brazil','Death_added'] ,
name='Brazil',
marker_color='blue',
width=bw*0.5,showlegend=False
),
row=3, col=1, secondary_y=True)
#fig.add_trace(go.Bar(x=pd.to_datetime(['2020-03-09'])
# , y=np.repeat(100000,1),name='events', marker_color='rgb(256,0,0)',width=bw*0.2,showlegend=False ),
# row=3, col=1, secondary_y=False)
#fig.add_annotation(x=pd.to_datetime('2020-03-10'),y=7000, ax=100,ay=0,xref='x3', yref='y5',arrowhead=1,
# text="Lockdown: Mar 09",font=dict(size=11))
#fig.add_annotation(x=pd.to_datetime('2020-03-22'),y=6500,ax=70,ay=0, xref='x3', yref='y5',arrowhead=1,
# text="Peak: Mar 21",font=dict(size=11))
#fig.add_annotation(x=pd.to_datetime('2020-05-15'),y=6000,ax=0,ay=0, xref='x3', yref='y5',
# text="From lockdown to peak:<br>12 days",font=dict(color="black",size=14))
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-02-23',date_max]), row=3, col=1,showgrid=True)
yr=35000
fig.update_yaxes(title_text='Case',range=[0,yr], row=3, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/5.], row=3, col=1, secondary_y=True,color='blue')
#Russia
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='Russia','Date_updated'],
y=dfa.loc[dfa.Country=='Russia','Confirmed_added'] ,
name='Russia',
marker_color='rgb(55, 83, 109)',
width=bw*0.5 ,showlegend=False
),
row=4, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='Russia','Date_updated'],
y=dfa.loc[dfa.Country=='Russia','Death_added'] ,
name='Russia',
marker_color='blue',
width=bw*0.5 ,showlegend=False
),
row=4, col=1, secondary_y=True)
#fig.add_trace(go.Bar(x=[pd.to_datetime('2020-02-25')]
# , y=[100000], name='events', marker_color='rgb(256,0,0)',width=bw*0.2,showlegend=False),
# row=4, col=1, secondary_y=False)
#fig.add_annotation(
# x=pd.to_datetime('2020-02-26'),y=1000,ax=120,ay=0,xref='x4',yref='y7',arrowhead=1,
# text="Soft lockdown <br> aggressive testing and tracing: <br> Feb 25", font=dict(size=11))
#fig.add_annotation(x=pd.to_datetime('2020-03-04'),y=700,ax=70, ay=0, xref='x4',yref='y7',arrowhead=1,
# text="Peak: Mar 3", font=dict(size=11))
#fig.add_annotation(
# x=pd.to_datetime('2020-05-03'),y=800,ax=0,ay=0,xref='x4',yref='y7',
# text="From aggressive measures to peak: <br> 7 days",font=dict( color="black",size=14))
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-02-23',date_max]), row=4, col=1,showgrid=True)
yr=12000
fig.update_yaxes(title_text='Case',range=[0,yr], row=4, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/5.], row=4, col=1, secondary_y=True,color='blue')
#United Kingdom
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='United Kingdom','Date_updated'],
y=dfa.loc[dfa.Country=='United Kingdom','Confirmed_added'] ,
name='United Kingdom',
marker_color='rgb(55, 83, 109)',
width=bw*0.5,showlegend=False
),
row=5, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=dfa.loc[dfa.Country=='United Kingdom','Date_updated'],
y=dfa.loc[dfa.Country=='United Kingdom','Death_added'] ,
name='United Kingdom',
marker_color='blue',
width=bw*0.5,showlegend=False
),
row=5, col=1, secondary_y=True)
#fig.add_trace(go.Bar(x=pd.to_datetime(['2020-01-23','2020-03-25'])
# , y=np.repeat(100000,2),name='events', marker_color='rgb(256,0,0)',width=bw*0.5,showlegend=False),
# row=5,col=1, secondary_y=False)
#fig.add_annotation(
# x=pd.to_datetime('2020-01-23'),y=16000,ax=80,ay=0,xref='x5',yref='y9',arrowhead=1,
# text="Hubei lockdown:<br> Jan 23", font=dict(size=11))
#fig.add_annotation(x=pd.to_datetime('2020-03-25'),y=12000,ax=-70, ay=0, xref='x5',yref='y9',arrowhead=1,
# text="Lockdown Lifted: <br> Mar 25", font=dict(size=11))
#fig.add_annotation(x=pd.to_datetime('2020-02-13'),y=10000,ax=70, ay=0, xref='x5',yref='y9',arrowhead=1,
# text="Peak: Feb 11", font=dict(size=11))
#fig.add_annotation(
# x=pd.to_datetime('2020-05-15'),y=14000,ax=0,ay=0,xref='x5',yref='y9',
# text="Lockdown to peak: <br> 21 days",font=dict( color="black",size=14))
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-02-23',date_max]), row=5, col=1,showgrid=True)
yr=9000
fig.update_yaxes(title_text='Case',range=[0,yr], row=5, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/5.], row=5, col=1, secondary_y=True,color='blue')
fig.update_layout(height=2500, width=800, showlegend=True, title_text="Daily New Adds",
font=dict(
family="Arial",
size=14,
color="black"
)
)
fig.show()
fig.write_image("output/daily_newadd_death_"+ dfa.Date_updated.max().strftime('_%m_%d_%Y')+".jpeg", scale=3)
dcan=df[df.Country=='Canada'].copy()
dcan.loc[:,'StartDate']=-999
for j in dcan.Region.unique():
sdate=dcan.loc[(dcan.Region==j) & (dcan.Confirmed > 100),'Date_updated'].min()
##print(f"Country: {j} case number: {dfa[(dfa.Country==j) & (dfa.Confirmed > 100)]['Confirmed'].min()} start date {sdate}")
tmp=dcan.loc[dcan.Region==j,'Date_updated']-sdate
dcan.loc[dcan.Region==j,'StartDate']=tmp.dt.days + 1
date_max='2020-06-25'
fig = make_subplots(
rows=4, cols=1,
subplot_titles=("Ontario", "Quebec","Alberta","British Columbia"),
vertical_spacing=0.08,
specs=[[{"secondary_y": True}],
[{"secondary_y": True}],
[{"secondary_y": True}],
[{"secondary_y": True}]])
bw=1000*3600*24
oneday=86400000.0
##Ontario
ixd=(df.Country=='Canada') & (df.Region =='Ontario')
fig.add_trace(go.Bar(x=df.loc[ixd ,'Date_updated'],
y=df.loc[ixd,'Confirmed_added'] ,
name='Case',
marker_color='rgb(55, 83, 109)',
width=bw*0.5,showlegend=False
),
row=1, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=df.loc[ixd,'Date_updated'],
y=df.loc[ixd,'Death_added'] ,
name='Death',
marker_color='blue',
width=bw*0.5,showlegend=False
),
row=1, col=1, secondary_y=True)
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-03-10',date_max]), row=1, col=1,showgrid=True)
yr=800
fig.update_yaxes(title_text='Case',range=[0,yr], row=1, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/5.], row=1, col=1, secondary_y=True,color='blue')
#Quebec
ixd=(df.Country=='Canada') & (df.Region =='Quebec')
fig.add_trace(go.Bar(x=df.loc[ixd ,'Date_updated'],
y=df.loc[ixd,'Confirmed_added'] ,
name='Case',
marker_color='rgb(55, 83, 109)',
width=bw*0.5 ,showlegend=False
),
row=2, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=df.loc[ixd,'Date_updated'],
y=df.loc[ixd,'Death_added'] ,
name='Death',
marker_color='blue',
width=bw*0.5 ,showlegend=False
),
row=2, col=1, secondary_y=True)
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-03-10',date_max]), row=2, col=1,showgrid=True)
yr=2250
fig.update_yaxes(title_text='Case',range=[0,yr], row=2, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/2.], row=2, col=1, secondary_y=True,color='blue')
#Alberta
ixd=(df.Country=='Canada') & (df.Region =='Alberta')
fig.add_trace(go.Bar(x=df.loc[ixd ,'Date_updated'],
y=df.loc[ixd,'Confirmed_added'] ,
name='Case',
marker_color='rgb(55, 83, 109)',
width=bw*0.5 ,showlegend=False
),
row=3, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=df.loc[ixd,'Date_updated'],
y=df.loc[ixd,'Death_added'] ,
name='Death',
marker_color='blue',
width=bw*0.5 ,showlegend=False
),
row=3, col=1, secondary_y=True)
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-03-10',date_max]), row=3, col=1,showgrid=True)
yr=400
fig.update_yaxes(title_text='Case',range=[0,yr], row=3, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/5.], row=3, col=1, secondary_y=True,color='blue')
#British Columbia
ixd=(df.Country=='Canada') & (df.Region =='British Columbia')
fig.add_trace(go.Bar(x=df.loc[ixd ,'Date_updated'],
y=df.loc[ixd,'Confirmed_added'] ,
name='Case',
marker_color='rgb(55, 83, 109)',
width=bw*0.5 ,showlegend=False
),
row=4, col=1, secondary_y=False)
fig.add_trace(go.Bar(x=df.loc[ixd,'Date_updated'],
y=df.loc[ixd,'Death_added'] ,
name='Death',
marker_color='blue',
width=bw*0.5 ,showlegend=False
),
row=4, col=1, secondary_y=True)
fig.update_xaxes(title_text="Date", showline=True,linewidth=1,showticklabels=True,
linecolor='black',ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',range=pd.to_datetime(['2020-03-10',date_max]), row=4, col=1,showgrid=True)
yr=200
fig.update_yaxes(title_text='Case',range=[0,yr], row=4, col=1, secondary_y=False)
fig.update_yaxes(title_text='Death',range=[0,yr/5.], row=4, col=1, secondary_y=True,color='blue')
fig.update_layout(height=2000, width=800, showlegend=True, title_text="Daily New Adds",
font=dict(
family="Arial",
size=14,
color="black"
)
)
fig.show()
fig.write_image("output/daily_newadd_death_Canada_"+ dfa.Date_updated.max().strftime('_%m_%d_%Y')+".jpeg", scale=3)
pv=['Alberta', 'British Columbia', 'Manitoba',
'New Brunswick', 'Newfoundland and Labrador', 'Nova Scotia',
'Ontario', 'Prince Edward Island', 'Quebec', 'Saskatchewan',
'Northwest Territories', 'Yukon']
pvs=['AB','BC','MB','NB','NL','NS','ON','PE','QC','SK','NT','YT']
#pv=['Alberta', 'British Columbia','Ontario','Quebec']
#pvs=['AB','BC','ON','QC']
dseq=pd.DataFrame({'Date_updated':[ pd.to_datetime('2020-03-11') + timedelta(days=x) for x in range(100)]})
x=np.arange(10)
xx=np.array([np.repeat(1,10),x]).transpose()
for i in range(len(pv)):
tmp=dcan.loc[dcan.Region==pv[i],['Date_updated','StartDate','Confirmed']]
tmp.columns=['Date_updated','StartDate_'+pvs[i],'Confirmed_'+pvs[i]]
dseq=dseq.merge(tmp,how='left',on='Date_updated')
mod=OLS(np.log(tmp.iloc[-5:,2]), xx[:5]).fit()
pdx=mod.get_prediction(xx)
predmean=np.exp(pdx.predicted_mean)
conf=np.exp(pdx.conf_int(alpha=0.05))
out=pd.DataFrame({'Date_updated': tmp.iloc[-5:,0].append(tmp.iloc[-5:,0]+timedelta(days=5)),
'predict_'+pvs[i]:predmean,
'cf_low_'+pvs[i]:conf[:,0],'cf_high_'+pvs[i]:conf[:,1]})
dseq=dseq.merge(out,how='left',on='Date_updated')
eve_ON=pd.DataFrame({'Date_updated':pd.to_datetime(['2020-03-17','2020-03-23','2020-03-27','2020-03-30']),
'Event_ON':['State of Emergency;<br>school closed','Non-essential business closed',
'Mandantory self-isolation for returning travellers','Outdoor recreational amenities closed']})
eve_BC=pd.DataFrame({'Date_updated':pd.to_datetime(['2020-03-18','2020-03-26']),
'Event_BC':['State of Emergency;<br>school closed','Non-essential business closed']})
eve_QC=pd.DataFrame({'Date_updated':pd.to_datetime(['2020-03-18','2020-03-25']),
'Event_QC':['State of Emergency;<br>school closed','Non-essential business closed']})
dseq=dseq.merge(eve_ON, how='left',on='Date_updated')
dseq=dseq.merge(eve_BC, how='left',on='Date_updated')
dseq=dseq.merge(eve_QC, how='left',on='Date_updated')
pv=[ 'British Columbia','Ontario','Alberta','Quebec']
pvs=['BC','ON','AB','QC']
clr=px.colors.qualitative.G10
fig = make_subplots(
rows=1, cols=2,
horizontal_spacing=0.07,
subplot_titles=("Linear","Logarithmic"))
#fig.add_trace(go.Scatter(log_y=False,range_x=['2020-03-08','2020-04-05'],range_y=[0,7000],width=800, height=500)
# ,row=1,col=1)
for i in range(len(pv)):
fig.add_trace(go.Scatter(x=dseq['Date_updated'],y=dseq['Confirmed_'+pvs[i]]
,mode="lines+markers",name=pvs[i],line=dict(width=2, color=clr[i]))
,row=1,col=1)
fig.add_trace(go.Scatter(x=dseq['Date_updated'],y=dseq['predict_'+pvs[i]]
,mode="lines",name=pvs[i]+' trend',line=dict(width=2, color=clr[i], dash='dot'))
,row=1,col=1)
fig.update_yaxes(title_text='Confirmed Cases',range=[0, 65000], row=1, col=1)
for i in range(len(pv)):
fig.add_trace(go.Scatter(x=dseq['Date_updated'],y=dseq['Confirmed_'+pvs[i]]
,mode="lines+markers",name=pvs[i],line=dict(width=2, color=clr[i]),showlegend=False)
,row=1,col=2)
fig.add_trace(go.Scatter(x=dseq['Date_updated'],y=dseq['predict_'+pvs[i]]
,mode="lines",name=pvs[i]+' trend',line=dict(width=2, color=clr[i], dash='dot'),showlegend=False)
,row=1,col=2)
fig.update_yaxes(range=[1, 5], row=1, col=2,type='log')
fig.update_xaxes(title_text="Date", range=pd.to_datetime(['2020-03-08','2020-06-30']),
ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',
row=1, col=1)
fig.update_xaxes(title_text="Date", range=pd.to_datetime(['2020-03-08','2020-06-30']),
ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside',
row=1, col=2)
fig.update_layout(height=500, width=1000, showlegend=True, title_text="COVID-19 Cases by Province",
legend=dict(x=0.01, y=0.95,font=dict(size=11,family='Ariel'),bgcolor='rgba(0,0,0,0)'),
font=dict(
family="Arial",
size=14,
color="black"
))
fig.show()
fig.write_image("output/trend_by_prov_"+ dfa.Date_updated.max().strftime('_%m_%d_%Y')+".jpeg", scale=3)
fig=px.line(log_y=True,range_x=['2020-03-08','2020-06-30'],range_y=[10,45000],width=800, height=500)
#fig=px.line(dfa[dfa.Country.isin(countrylist)],x='StartDate',y='Confirmed',color='Country',log_y=True
# ,range_x=[0,40],range_y=[100,100000])
#pv=['Alberta', 'British Columbia','Ontario','Quebec']
#clr=['blue','green','red','orange']
#clr=px.colors.qualitative.Dark24
i=0
fig.add_scatter(x=dseq['Date_updated'],y=dseq['Confirmed_'+pvs[i]]
,mode="lines+markers+text",name=pvs[i],line=dict(width=2, color=clr[i]),
text=dseq['Event_'+pvs[i]],textposition="bottom right",
textfont=dict(family="Ariel",size=11,color=clr[i]))
fig.add_scatter(x=dseq['Date_updated'],y=dseq['predict_'+pvs[i]]
,mode="lines",name=pvs[i]+' trend',line=dict(width=2, color=clr[i], dash='dot'))
i=1
fig.add_scatter(x=dseq['Date_updated'],y=dseq['Confirmed_'+pvs[i]]
,mode="lines+markers+text",name=pvs[i],line=dict(width=2, color=clr[i]),
text=dseq['Event_'+pvs[i]],textposition="top left",
textfont=dict(family="Ariel",size=11,color=clr[i]))
fig.add_scatter(x=dseq['Date_updated'],y=dseq['predict_'+pvs[i]]
,mode="lines",name=pvs[i]+' trend',line=dict(width=2, color=clr[i], dash='dot'))
fig.update_xaxes(
ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside')
fig.update_layout(
title="COVID-19 Cases for ON and BC",
xaxis_title="Date",
yaxis_title="Confirmed Case",
font=dict(
family="Ariel",
size=15,
color="black"
)
)
fig.show()
fig.write_image("output/trend_by_prov_ON_BC"+ dcan.Date_updated.max().strftime('_%m_%d_%Y')+".jpeg",scale=3.0)
pl=['Prince Edward Island','Northwest Territories','Nunavut','Yukon','Repatriated travellers']
tmp=df[df.Country=='Canada'].copy()
tmp['Province']=[x if x not in pl else 'other' for x in tmp['Region'] ]
tmp=tmp.groupby(['Date_updated','Province'])['Confirmed_added'].sum().reset_index()
tmp.rename(columns={'Confirmed_added':'Daily Adds','Date_updated':'Date'},inplace=True)
fig=px.bar(tmp,x='Date',y='Daily Adds',color='Province', range_x=['2020-03-08','2020-06-30'],range_y=[0,2800])
fig.update_xaxes(showgrid=True,
ticklen=10,tickwidth=2,tickcolor='black',dtick=7*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside')
fig.update_layout(
width=1000, height=500,
title="Daily New Adds by Province",
xaxis_title="Date",
yaxis_title="Daily Adds",
font=dict(
family="Ariel",
size=15,
color="black"
)
)
fig.show()
fig.write_image("output/dailyadds_prov_"+ dcan.Date_updated.max().strftime('_%m_%d_%Y')+".jpeg",scale=3.0)
tmp=dfa.loc[dfa.Country=='Italy',['Date_updated','Confirmed_added']].copy()
peakdate=tmp.loc[tmp['Confirmed_added']==tmp['Confirmed_added'].max(),'Date_updated'].iloc[0]
x=(tmp.loc[tmp['Date_updated']>=peakdate,'Date_updated']-peakdate).dt.days
y=tmp.loc[tmp['Date_updated']>=peakdate,'Confirmed_added']
xx=np.array([np.repeat(1,len(x)),x]).transpose()
mod_italy=OLS(y, xx).fit()
xpred=np.array([np.repeat(1,100),np.arange(100)]).transpose()
pdx=mod_italy.get_prediction(xpred)
predmean=pdx.predicted_mean
conf=pdx.conf_int(alpha=0.05)
out_italy=pd.DataFrame({'Date_updated': [peakdate + timedelta(days=x) for x in range(100)],
'predict':predmean,
'cf_low':conf[:,0],'cf_high':conf[:,1]})
tcan=dfa.loc[dfa.Country=='Canada',['Date_updated','Confirmed_added']].copy()
ptmp=tcan.loc[tcan['Date_updated']<'2020-05-01','Confirmed_added'].max()
#ptmp=tcan['Confirmed_added'].max()
peakdate=tcan.loc[tcan['Confirmed_added']==ptmp,'Date_updated'].iloc[0]
x=(tcan.loc[tcan['Date_updated']>=peakdate,'Date_updated']-peakdate).dt.days
y=tcan.loc[tcan['Date_updated']>=peakdate,'Confirmed_added']
xx=np.array([np.repeat(1,len(x)),x]).transpose()
mod=OLS(y, xx).fit()
xpred=np.array([np.repeat(1,150),np.arange(150)]).transpose()
pdx=mod.get_prediction(xpred)
predmean=pdx.predicted_mean
conf=pdx.conf_int(alpha=0.05)
b_italy=mod_italy.params.x1*mod.params.const/mod_italy.params.const
a_italy=mod.params.const
out=pd.DataFrame({'Date_updated': [peakdate + timedelta(days=x) for x in range(150)],
'predict':predmean,
'cf_low':conf[:,0],'cf_high':conf[:,1],
'predict_italy': np.arange(150)*b_italy+a_italy})
px.line(out,x='Date_updated',y='predict')
fig=px.bar(tcan,x='Date_updated',y='Confirmed_added', range_x=['2020-03-08','2020-07-25'],range_y=[0,2800],width=900,height=500)
fig.add_scatter(x=out['Date_updated'],y=out['cf_low'],fill=None,
mode='lines',line_color='rgba(0,0,0,0)',showlegend=False)
fig.add_scatter(x=out['Date_updated'],y=out['cf_high'],fill='tonexty',
mode='lines',line_color='rgba(169,169,169,0.1)',showlegend=False)
fig.add_scatter(x=out['Date_updated'],y=out['predict_italy']
,mode="lines",line=dict(color='green',dash='dot'), name='Scaled Italy Trend')
fig.add_scatter(x=out['Date_updated'],y=out['predict']
,mode="lines",line_color='red', name='Linear Projection')
fig.update_xaxes(
ticklen=10,tickwidth=2,tickcolor='black',dtick=10*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside')
fig.update_layout(
title="Canada - Daily New Adds",
xaxis_title="Date",
yaxis_title="Daily Adds",
font=dict(
family="Ariel",
size=15,
color="black"
),
legend=dict(x=0.7, y=0.95,font=dict(size=11,family='Ariel'),bgcolor='rgba(0,0,0,0)')
)
fig.show()
fig=px.bar(tmp,x='Date_updated',y='Confirmed_added', range_x=['2020-02-08','2020-06-25'],range_y=[0,7000],width=900,
height=500)
fig.add_scatter(x=out_italy['Date_updated'],y=out_italy['cf_low'],fill=None,
mode='lines',line_color='rgba(0,0,0,0)',showlegend=False)
fig.add_scatter(x=out_italy['Date_updated'],y=out_italy['cf_high'],fill='tonexty',
mode='lines',line_color='rgba(169,169,169,0.1)',showlegend=False)
fig.add_scatter(x=out_italy['Date_updated'],y=out_italy['predict'],
mode="lines",line_color='red', name="Linear Projection")
fig.update_xaxes(
ticklen=10,tickwidth=2,tickcolor='black',dtick=10*oneday,tickformat= "%d-%b",
tickangle=30,
ticks='outside')
fig.update_layout(
title="Italy - Daily New Adds",
xaxis_title="Date",
yaxis_title="Daily Adds",
font=dict(
family="Ariel",
size=15,
color="black"
),
legend=dict(x=0.8, y=0.95,font=dict(size=11,family='Ariel'),bgcolor='rgba(0,0,0,0)')
)
fig.show()